package com.woniu108.evaluate.service.impl;


import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.woniu108.carService.commos.dto.ProductInfoDto;
import com.woniu108.carService.commos.dto.UserInfoDto;
import com.woniu108.carService.commos.exception.WoniuException;
import com.woniu108.carService.commos.exception.evaluate.EvaluateException;
import com.woniu108.carService.commos.exception.evaluate.EvaluateExceptionCode;
import com.woniu108.carService.commos.exception.orderProduct.OrderProductException;
import com.woniu108.carService.commos.exception.orderProduct.OrderProductExceptionCode;
import com.woniu108.carService.commos.model.Result;
import com.woniu108.carService.commos.util.RedisKey;
import com.woniu108.carService.commos.util.RedisUtil;
import com.woniu108.carService.commos.util.StaticData;
import com.woniu108.evaluate.client.OrderClient;
import com.woniu108.evaluate.client.PersonClient;
import com.woniu108.evaluate.client.ProductClient;
import com.woniu108.evaluate.dto.ProductReviewDto;
import com.woniu108.evaluate.mapper.ProductReviewMapper;
import com.woniu108.evaluate.model.ProductReview;
import com.woniu108.evaluate.param.ProductReviewPublishParam;
import com.woniu108.evaluate.param.ProductReviewReplyParam;
import com.woniu108.evaluate.service.ProductReviewService;
import com.woniu108.order.model.dto.OrderProductDto;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;

/**
 * <p>
 * 商品评价表 服务实现类
 * </p>
 *
 * @author yanxi
 * @since 2024-05-23
 */
@Service
public class ProductReviewServiceImpl extends ServiceImpl<ProductReviewMapper, ProductReview> implements ProductReviewService {
    @Resource
    private ProductReviewMapper productReviewMapper;
    @Resource
    private OrderClient orderClient;
    @Resource
    private RedisUtil redisUtil;
    @Resource
    private PersonClient personClient;
    @Resource
    private ProductClient productClient;

    /**
     * 查询商品评价集合
     * @param pItemId 商品id
     * @return 商品评价集合
     */
    @Override
    public List<ProductReviewDto> selectProductReviewByPItemId(Integer pItemId) {
        Result<List<ProductInfoDto>> allProductInfoResult = productClient.findAllProductInfo(pItemId);
        System.out.println(allProductInfoResult);
        if(allProductInfoResult.getCode()!=200){
            throw new WoniuException(allProductInfoResult.getMsg(),allProductInfoResult.getCode());
        }
        List<ProductInfoDto> productInfoDtos = allProductInfoResult.getData();

        //查询
        QueryWrapper<ProductReview> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("reply_re_id",0);
        //用户商品评价
        List<ProductReview> productReviews = productReviewMapper.selectList(queryWrapper);

        //预备评价集合
        List<ProductReviewDto> productReviewDtos= new ArrayList<>();
        for(ProductReview productReview:productReviews){
            for (ProductInfoDto productInfoDto:productInfoDtos){
                if (productReview.getPInfoId().equals(productInfoDto.getPInfoId())) {
                    ProductReviewDto reviewDto = BeanUtil.toBean(productReview, ProductReviewDto.class);
                    System.out.println(reviewDto.getSpokeId());
                    Result<UserInfoDto> userInfoDtoResult = personClient.getByUserId(reviewDto.getSpokeId());
                    if(userInfoDtoResult.getCode()!=200){
                        throw new WoniuException(userInfoDtoResult.getMsg(),userInfoDtoResult.getCode());
                    }
                    UserInfoDto userInfoDto = userInfoDtoResult.getData();
                    reviewDto.setSpokeNickname(userInfoDto.getUserNickName());
                    ProductReview replyReview = productReviewMapper.selectOne(new QueryWrapper<ProductReview>().eq("reply_re_id", reviewDto.getProReviewId()));
                    if(replyReview!=null){
                        reviewDto.setReplyReview(replyReview.getReview());
                    }
                    productReviewDtos.add(reviewDto);
                    break;
                }
            }
        }
        return productReviewDtos;
    }

    @Override
    @Transactional(rollbackFor = Throwable.class)
    public Boolean publishReviewsByUser(ProductReviewPublishParam param) {
        //查询订单状况
        Result<OrderProductDto> orderProductDtoResult = orderClient.queryOrderProductByOrderNum(param.getOrderProductNum());
        if(orderProductDtoResult.getCode()!=200){
            throw new WoniuException(orderProductDtoResult.getMsg(),orderProductDtoResult.getCode());
        }
        OrderProductDto orderProductDto = orderProductDtoResult.getData();
        //订单是否存在或删除
        if(orderProductDto.getOrderProductNum()==null||orderProductDto.getOrderProductState().equals(StaticData.ORDER_PRODUCT_STATE_DELETED)){
            throw new OrderProductException(OrderProductExceptionCode.ORDER_NULL);
        }
        //用户是否能操作
        if(!orderProductDto.getUserId().equals(param.getSpokeId())){
            throw new OrderProductException(OrderProductExceptionCode.ORDER_PRODUCT_USER_NOT_POWER);
        }
        //循环查询订单是否存在该商品
        boolean bool=false;
        Set<Object> pInfoIds = redisUtil.sMembers(RedisKey.orderProductPInfoSet(orderProductDto.getOrderProductNum()));
        for (Object pInfoId:pInfoIds) {
            if(pInfoId.equals(param.getPInfoId())){
                bool=true;
            }
        }
        if(!bool){
            throw new EvaluateException(EvaluateExceptionCode.PRODUCT_NO_EQUAL_ORDER);
        }
        //查询
        QueryWrapper<ProductReview> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("order_product_num",param.getOrderProductNum());
        queryWrapper.eq("p_info_id",param.getPInfoId());
        queryWrapper.eq("spoke_id",param.getSpokeId());
        ProductReview productReview = productReviewMapper.selectOne(queryWrapper);
        if(productReview!=null){
            throw new EvaluateException(EvaluateExceptionCode.EVALUATE_ALREADY_REVIEWED);
        }
        productReview=new ProductReview();
        productReview.setSpokeId(param.getSpokeId());
        productReview.setPInfoId(param.getPInfoId());
        productReview.setReview(param.getReview());
        productReview.setOrderProductNum(param.getOrderProductNum());
        productReview.setReplyReId(0);
        productReviewMapper.insert(productReview);
        return true;
    }

    @Override
    @Transactional(rollbackFor = Throwable.class)
    public Boolean replyByReview(ProductReviewReplyParam param) {
        ProductReview productReview = productReviewMapper.selectById(param.getProReviewId());
        if(productReview==null){
            throw new EvaluateException(EvaluateExceptionCode.EVALUATE_REVIEW_NO_EXISTED);
        }
        ProductReview replyReview = productReviewMapper.selectOne(new QueryWrapper<ProductReview>().eq("reply_re_id", param.getProReviewId()));
        if(replyReview!=null){
            throw new EvaluateException(EvaluateExceptionCode.EVALUATE_REVIEW_REPLY_EXISTED);
        }
        replyReview=new ProductReview();
        replyReview.setReplyId(param.getAdminId());
        replyReview.setReview(param.getReview());
        replyReview.setReplyReId(param.getProReviewId());
        productReviewMapper.insert(replyReview);
        return true;
    }

    @Override
    @Transactional(rollbackFor = Throwable.class)
    public Boolean delReviewByIdToUser(Integer proReviewId, String userId) {
        ProductReview productReview = productReviewMapper.selectById(proReviewId);
        if(productReview==null){
            throw new EvaluateException(EvaluateExceptionCode.EVALUATE_REVIEW_NO_EXISTED);
        }
        if(!productReview.getSpokeId().equals(userId)){
            throw new EvaluateException(EvaluateExceptionCode.EVALUATE_REVIEW_USER_NOT_POWER);
        }
        productReviewMapper.deleteById(proReviewId);
        return true;
    }

    @Override
    @Transactional(rollbackFor = Throwable.class)
    public Boolean delReviewById(Integer proReviewId) {
        ProductReview productReview = productReviewMapper.selectById(proReviewId);
        if(productReview==null){
            throw new EvaluateException(EvaluateExceptionCode.EVALUATE_REVIEW_NO_EXISTED);
        }
        productReviewMapper.deleteById(proReviewId);
        return true;
    }
}
